home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / telecomm / sticpsrc.lzh / SOURCE.ARC / AMIGA_UT.C < prev    next >
C/C++ Source or Header  |  1990-03-11  |  5KB  |  201 lines

  1. /*  C K I U T L --  Utility functions for C-Kermit on the Amiga */
  2.  
  3. /*
  4.  Author: Jack Rouse
  5.  Contributed to Columbia University for inclusion in C-Kermit.
  6.  Copyright (C) 1986, Jack J. Rouse, 106 Rubin Ct. Apt. A-4, Cary NC 27511
  7.  Permission is granted to any individual or institution to use, copy, or
  8.  redistribute this software so long as it is not sold for profit, provided this
  9.  copyright notice is retained. 
  10.  
  11.  The file status routines assume all file protection modes are real, instead
  12.  of just delete protection on files and write protection on disks.
  13. */
  14.  
  15. #include <stdio.h>
  16. #include "exec/types.h"
  17. #include "exec/exec.h"
  18. #include "libraries/dos.h"
  19. #include "libraries/dosextens.h"
  20.  
  21. LONG Execute();
  22. LONG IoErr();
  23. BPTR Lock();
  24. VOID UnLock();   
  25.  
  26. /* portable library */
  27. char *malloc();
  28.  
  29. /* Amiga Kermit externals (defined in ckitio.c) */
  30.  
  31. extern struct Process *MyProc;
  32. extern struct CommandLineInterface *MyCLI;
  33.  
  34. /*
  35.  * getwd -- get current working directory text
  36.  */
  37. char *getwd(buf, len)
  38. register char *buf;
  39. int len;
  40. {
  41.     register UBYTE *dirname;
  42.  
  43.     if (MyCLI == NULL) return(NULL);
  44.     dirname = (UBYTE *)BADDR(MyCLI->cli_SetName);
  45.     if (len < *dirname + 1) return(NULL);
  46.     strncpy(buf, dirname + 1, *dirname);
  47.     buf[*dirname] = 0;
  48.     return(buf);
  49. }
  50.  
  51. /*
  52.  * system(cmd) -- execute a command
  53.  *    provides no sensible return value
  54.  */
  55. system(cmd)
  56. char *cmd;
  57. {
  58.     BPTR fh;
  59.  
  60.     fflush(stdout);
  61.     Execute(cmd, (BPTR)NULL, (BPTR)NULL);
  62. }
  63. /*
  64.  * update the current directory name in the CLI process structure
  65.  *
  66.  * This version generates the new name from the current name and
  67.  * the specified path, something like the CD command does.
  68.  * A much better version could be written using Parent(), Examine(),
  69.  * and VolInfo to reconstitute a name from a lock, but Parent() doesn't
  70.  * work with RAM: in V1.1.  The current implementation, like the CD
  71.  * command, has difficulty with backing up the directory tree.  For example
  72.  * { chdir("c:"); chdir("/"); } results in a dir name of "c:/".  However,
  73.  * this version shouldn't get as far out of sync as the CD command.  (The
  74.  * same sequence with the CD command puts you in the parent dir of "c:" but
  75.  * with a directory name of "c:".)
  76.  */
  77. static void update_dirname(name)
  78. register char *name;
  79. {
  80.     register UBYTE *dirname;        /* DOS directory name BSTR */
  81.     char buf[100];                /* about same size as DOS */
  82.     register char *tail;
  83.  
  84.     /* locate the DOS copy of the directory name */
  85.     if (MyCLI == NULL) return;
  86.     dirname = (UBYTE *)BADDR(MyCLI->cli_SetName);
  87.  
  88.     /* if the name is anchored (like "DF1:") simply replace the name */
  89.     if (rindex(name, ':') != NULL)
  90.     {
  91.         *dirname = strlen(name);
  92.         strncpy(&dirname[1], name, *dirname);
  93.         return;
  94.     }
  95.  
  96.     /* name is relative to current directory, copy name to work with */
  97.     strncpy(buf, &dirname[1], *dirname);
  98.     tail = &buf[*dirname];
  99.  
  100.     /* traverse the path in the name */
  101.     while (*name)
  102.     {
  103.         /* go to parent dir? */
  104.         if (*name == '/')
  105.         {    /* remove a component from the directory path */
  106.  
  107.             /* advance past parent slash */
  108.             ++name;
  109.  
  110.             /* if at colon, can't back up */
  111.             if (tail[-1] == ':')
  112.             {
  113.                 *tail++ = '/';
  114.                 continue;
  115.             }
  116.  
  117.             /* if at slash, see if name given */
  118.             if (tail[-1] == '/')
  119.             {
  120.                 /* if no name, can't back up */
  121.                 if (tail[-2] == '/' || tail[-2] == ':')
  122.                 {
  123.                     *tail++ = '/';
  124.                     continue;
  125.                 }
  126.  
  127.                 /* remove trailing slash */
  128.                 --tail;
  129.             }
  130.  
  131.             /* remove remainder of component */
  132.             while (tail[-1] != '/' && tail[-1] != ':')
  133.                 --tail;
  134.         }
  135.         else
  136.         {    /* add component to directory path */
  137.             /* add slash if necessary to separate name */
  138.             if (tail[-1] != ':' && tail[-1] != '/')
  139.                 *tail++ = '/';
  140.  
  141.             /* add component name */
  142.             while (*name && *name != '/')
  143.                 *tail++ = *name++;
  144.  
  145.             /* add trailing slash if specified */
  146.             if (*name == '/')
  147.                 *tail++ = *name++;
  148.         }
  149.     }
  150.  
  151.     /* set BSTR to derived name */
  152.     *dirname = tail - buf;
  153.     strncpy(&dirname[1], buf, *dirname);
  154. }
  155.  
  156. /*
  157.  * change current directory
  158.  */
  159. int chdir(name)
  160. char *name;
  161. {
  162.     BPTR lock;
  163.     BPTR oldlock;
  164.     struct FileInfoBlock *fib;
  165.  
  166.     /* ignore chdir("") */
  167.     if (*name == '\0') return(0);
  168.  
  169.     /* try to look at the object */ 
  170.     lock = Lock(name, (LONG)ACCESS_READ);
  171.     if (lock == NULL) return(-1);
  172.  
  173.     /* make sure the file is a directory */
  174.     fib = (struct FileInfoBlock *)malloc(sizeof(*fib));
  175.     if (fib == NULL || !Examine(lock, fib) || fib->fib_DirEntryType <= 0)
  176.     {
  177.         if (fib) free(fib);
  178.         if ( lock >= 0 )
  179.             UnLock(lock);
  180.         return(-1);
  181.     }
  182.  
  183.     /* don't need file info any more */
  184.     free(fib);
  185.  
  186.     /* change the current directory */
  187.     oldlock = CurrentDir(lock);
  188.  
  189.     /* update the DOS copy of the directory name */
  190.     update_dirname(name);
  191.  
  192.     /* unlock the previous current directory */
  193.     if (oldlock)
  194.     {
  195.         if ( oldlock >= 0)
  196.             UnLock(oldlock);
  197.     }
  198.  
  199.     return(0);
  200. }
  201.